using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Web;
using PickGold.Charting.Utilities;
using PickGold.Charting.Design;

namespace PickGold.Charting
{
	[SRDescription("DescriptionAttributeCalloutAnnotation_CalloutAnnotation"), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
	public class CalloutAnnotation : TextAnnotation
	{
		private LineAnchorCapStyle _calloutAnchorCap = LineAnchorCapStyle.Arrow;
		private CalloutStyle _calloutStyle = CalloutStyle.Rectangle;
		private static RectangleF _cloudBounds = RectangleF.Empty;
		private static GraphicsPath _cloudOutlinePath = null;
		private static GraphicsPath _cloudPath = null;

		public CalloutAnnotation()
		{
			base.anchorOffsetX = 3.0;
			base.anchorOffsetY = 3.0;
			base.anchorAlignment = ContentAlignment.BottomLeft;
		}

		private GraphicsPath CreateRoundedRectPath(RectangleF rect, float cornerRadius)
		{
			var path = new GraphicsPath();
			int segments = 10;
			this.PathAddLineAsSegments(path, rect.X + cornerRadius, rect.Y, rect.Right - cornerRadius, rect.Y, segments);
			path.AddArc(rect.Right - (2f * cornerRadius), rect.Y, 2f * cornerRadius, 2f * cornerRadius, 270f, 90f);
			this.PathAddLineAsSegments(path, rect.Right, rect.Y + cornerRadius, rect.Right, rect.Bottom - cornerRadius, segments);
			path.AddArc((float)(rect.Right - (2f * cornerRadius)), (float)(rect.Bottom - (2f * cornerRadius)), (float)(2f * cornerRadius), (float)(2f * cornerRadius), 0f, 90f);
			this.PathAddLineAsSegments(path, rect.Right - cornerRadius, rect.Bottom, rect.X + cornerRadius, rect.Bottom, segments);
			path.AddArc(rect.X, rect.Bottom - (2f * cornerRadius), 2f * cornerRadius, 2f * cornerRadius, 90f, 90f);
			this.PathAddLineAsSegments(path, rect.X, rect.Bottom - cornerRadius, rect.X, rect.Y + cornerRadius, segments);
			path.AddArc(rect.X, rect.Y, 2f * cornerRadius, 2f * cornerRadius, 180f, 90f);
			return path;
		}

		private GraphicsPath DrawCloudCallout(ChartGraphics graphics, RectangleF rectanglePosition, PointF anchorPoint)
		{
			RectangleF absoluteRectangle = graphics.GetAbsoluteRectangle(rectanglePosition);
			if ((!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) && !rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y))
			{
				PointF absolutePoint = graphics.GetAbsolutePoint(new PointF(rectanglePosition.X + (rectanglePosition.Width / 2f), rectanglePosition.Y + (rectanglePosition.Height / 2f)));
				SizeF absoluteSize = graphics.GetAbsoluteSize(new SizeF(rectanglePosition.Width, rectanglePosition.Height));
				absoluteSize.Width /= 10f;
				absoluteSize.Height /= 10f;
				PointF secondPoint = graphics.GetAbsolutePoint(new PointF(anchorPoint.X, anchorPoint.Y));
				PointF tf3 = secondPoint;
				float num = secondPoint.X - absolutePoint.X;
				float num2 = secondPoint.Y - absolutePoint.Y;
				PointF empty = PointF.Empty;
				if (anchorPoint.Y < rectanglePosition.Y)
				{
					empty = GetIntersectionY(absolutePoint, secondPoint, absoluteRectangle.Y);
					if (empty.X < absoluteRectangle.X)
					{
						empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.X);
					}
					else if (empty.X > absoluteRectangle.Right)
					{
						empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.Right);
					}
				}
				else if (anchorPoint.Y > rectanglePosition.Bottom)
				{
					empty = GetIntersectionY(absolutePoint, secondPoint, absoluteRectangle.Bottom);
					if (empty.X < absoluteRectangle.X)
					{
						empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.X);
					}
					else if (empty.X > absoluteRectangle.Right)
					{
						empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.Right);
					}
				}
				else if (anchorPoint.X < rectanglePosition.X)
				{
					empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.X);
				}
				else
				{
					empty = GetIntersectionX(absolutePoint, secondPoint, absoluteRectangle.Right);
				}
				SizeF ef3 = new SizeF(Math.Abs((float)(absolutePoint.X - empty.X)), Math.Abs((float)(absolutePoint.Y - empty.Y)));
				if (num > 0f)
				{
					num -= ef3.Width;
				}
				else
				{
					num += ef3.Width;
				}
				if (num2 > 0f)
				{
					num2 -= ef3.Height;
				}
				else
				{
					num2 += ef3.Height;
				}
				for (int i = 0; i < 3; i++)
				{
					using (GraphicsPath path = new GraphicsPath())
					{
						path.AddEllipse(tf3.X - (absoluteSize.Width / 2f), tf3.Y - (absoluteSize.Height / 2f), absoluteSize.Width, absoluteSize.Height);
						graphics.DrawPathAbs(path, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, 1, this.LineDashStyle, PenAlignment.Center, this.ShadowOffset, this.ShadowColor);
						absoluteSize.Width *= 1.5f;
						absoluteSize.Height *= 1.5f;
						tf3.X -= (num / 3f) + (i * (num / 10f));
						tf3.Y -= (num2 / 3f) + (i * (num2 / 10f));
					}
				}
			}
			GraphicsPath cloudPath = GetCloudPath(absoluteRectangle);
			graphics.DrawPathAbs(cloudPath, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, 1, this.LineDashStyle, PenAlignment.Center, this.ShadowOffset, this.ShadowColor);
			using (GraphicsPath path3 = GetCloudOutlinePath(absoluteRectangle))
			{
				graphics.DrawPathAbs(path3, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, 1, this.LineDashStyle, PenAlignment.Center);
			}
			base.DrawText(graphics, rectanglePosition, true, false);
			return cloudPath;
		}

		private GraphicsPath DrawPerspectiveCallout(ChartGraphics graphics, RectangleF rectanglePosition, PointF anchorPoint)
		{
			graphics.FillRectangleRel(rectanglePosition, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, this.ShadowColor, 0, PenAlignment.Center);
			GraphicsPath path = new GraphicsPath();
			path.AddRectangle(graphics.GetAbsoluteRectangle(rectanglePosition));
			base.DrawText(graphics, rectanglePosition, false, false);
			if ((!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) && !rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y))
			{
				Color[] colorArray = new Color[2];
				Color beginColor = this.BackColor.IsEmpty ? Color.White : this.BackColor;
				colorArray[0] = graphics.GetBrightGradientColor(beginColor, 0.6);
				colorArray[1] = graphics.GetBrightGradientColor(beginColor, 0.8);
				GraphicsPath[] pathArray = new GraphicsPath[2];
				using (pathArray[0] = new GraphicsPath())
				{
					using (pathArray[1] = new GraphicsPath())
					{
						RectangleF absoluteRectangle = graphics.GetAbsoluteRectangle(rectanglePosition);
						PointF absolutePoint = graphics.GetAbsolutePoint(anchorPoint);
						if (anchorPoint.Y < rectanglePosition.Y)
						{
							PointF[] points = new PointF[] { new PointF(absoluteRectangle.X, absoluteRectangle.Y), new PointF(absoluteRectangle.Right, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
							pathArray[0].AddLines(points);
							if (anchorPoint.X < rectanglePosition.X)
							{
								PointF[] tfArray2 = new PointF[] { new PointF(absoluteRectangle.X, absoluteRectangle.Bottom), new PointF(absoluteRectangle.X, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
								pathArray[1].AddLines(tfArray2);
							}
							else if (anchorPoint.X > rectanglePosition.Right)
							{
								PointF[] tfArray3 = new PointF[] { new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom), new PointF(absoluteRectangle.Right, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
								pathArray[1].AddLines(tfArray3);
							}
						}
						else if (anchorPoint.Y > rectanglePosition.Bottom)
						{
							PointF[] tfArray4 = new PointF[] { new PointF(absoluteRectangle.X, absoluteRectangle.Bottom), new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom), new PointF(absolutePoint.X, absolutePoint.Y) };
							pathArray[0].AddLines(tfArray4);
							if (anchorPoint.X < rectanglePosition.X)
							{
								PointF[] tfArray5 = new PointF[] { new PointF(absoluteRectangle.X, absoluteRectangle.Bottom), new PointF(absoluteRectangle.X, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
								pathArray[1].AddLines(tfArray5);
							}
							else if (anchorPoint.X > rectanglePosition.Right)
							{
								PointF[] tfArray6 = new PointF[] { new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom), new PointF(absoluteRectangle.Right, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
								pathArray[1].AddLines(tfArray6);
							}
						}
						else if (anchorPoint.X < rectanglePosition.X)
						{
							PointF[] tfArray7 = new PointF[] { new PointF(absoluteRectangle.X, absoluteRectangle.Bottom), new PointF(absoluteRectangle.X, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
							pathArray[1].AddLines(tfArray7);
						}
						else if (anchorPoint.X > rectanglePosition.Right)
						{
							PointF[] tfArray8 = new PointF[] { new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom), new PointF(absoluteRectangle.Right, absoluteRectangle.Y), new PointF(absolutePoint.X, absolutePoint.Y) };
							pathArray[1].AddLines(tfArray8);
						}
						int index = 0;
						foreach (GraphicsPath path2 in pathArray)
						{
							if (path2.PointCount > 0)
							{
								path2.CloseAllFigures();
								graphics.DrawPathAbs(path2, colorArray[index], this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, PenAlignment.Center);
								path.SetMarkers();
								path.AddPath(path2, false);
							}
							index++;
						}
					}
				}
			}
			return path;
		}

		private GraphicsPath DrawRectangleCallout(ChartGraphics graphics, RectangleF rectanglePosition, PointF anchorPoint)
		{
			GraphicsPath path = null;
			bool flag = false;
			if (!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y))
			{
				SizeF relativeSize = graphics.GetRelativeSize(new SizeF(1f, 1f));
				RectangleF ef2 = new RectangleF(rectanglePosition.Location, rectanglePosition.Size);
				ef2.Inflate(relativeSize);
				if (!ef2.Contains(anchorPoint.X, anchorPoint.Y))
				{
					flag = true;
					RectangleF absoluteRectangle = graphics.GetAbsoluteRectangle(rectanglePosition);
					PointF absolutePoint = graphics.GetAbsolutePoint(new PointF(anchorPoint.X, anchorPoint.Y));
					float num = Math.Min(absoluteRectangle.Width, absoluteRectangle.Height) / 4f;
					PointF[] points = new PointF[7];
					if ((anchorPoint.X < rectanglePosition.X) && (anchorPoint.Y > rectanglePosition.Bottom))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[3] = new PointF(absoluteRectangle.X + num, absoluteRectangle.Bottom);
						points[4] = absolutePoint;
						points[5] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom - num);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom - num);
					}
					else if (((anchorPoint.X >= rectanglePosition.X) && (anchorPoint.X <= rectanglePosition.Right)) && (anchorPoint.Y > rectanglePosition.Bottom))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[3] = new PointF((absoluteRectangle.X + (absoluteRectangle.Width / 2f)) + num, absoluteRectangle.Bottom);
						points[4] = absolutePoint;
						points[5] = new PointF((absoluteRectangle.X + (absoluteRectangle.Width / 2f)) - num, absoluteRectangle.Bottom);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
					}
					else if ((anchorPoint.X > rectanglePosition.Right) && (anchorPoint.Y > rectanglePosition.Bottom))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom - num);
						points[3] = absolutePoint;
						points[4] = new PointF(absoluteRectangle.Right - num, absoluteRectangle.Bottom);
						points[5] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
					}
					else if (((anchorPoint.X > rectanglePosition.Right) && (anchorPoint.Y <= rectanglePosition.Bottom)) && (anchorPoint.Y >= rectanglePosition.Y))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, (absoluteRectangle.Y + (absoluteRectangle.Height / 2f)) - num);
						points[3] = absolutePoint;
						points[4] = new PointF(absoluteRectangle.Right, (absoluteRectangle.Y + (absoluteRectangle.Height / 2f)) + num);
						points[5] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
					}
					else if ((anchorPoint.X > rectanglePosition.Right) && (anchorPoint.Y < rectanglePosition.Y))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right - num, absoluteRectangle.Y);
						points[2] = absolutePoint;
						points[3] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y + num);
						points[4] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[5] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
					}
					else if (((anchorPoint.X >= rectanglePosition.X) && (anchorPoint.X <= rectanglePosition.Right)) && (anchorPoint.Y < rectanglePosition.Y))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF((absoluteRectangle.X + (absoluteRectangle.Width / 2f)) - num, absoluteRectangle.Y);
						points[2] = absolutePoint;
						points[3] = new PointF((absoluteRectangle.X + (absoluteRectangle.Width / 2f)) + num, absoluteRectangle.Y);
						points[4] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[5] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
					}
					else if ((anchorPoint.X < rectanglePosition.X) && (anchorPoint.Y < rectanglePosition.Y))
					{
						points[0] = absolutePoint;
						points[1] = new PointF(absoluteRectangle.X + num, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[3] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[4] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
						points[5] = new PointF(absoluteRectangle.X, absoluteRectangle.Y + num);
						points[6] = new PointF(absoluteRectangle.X, absoluteRectangle.Y + num);
					}
					else if (((anchorPoint.X < rectanglePosition.X) && (anchorPoint.Y >= rectanglePosition.Y)) && (anchorPoint.Y <= rectanglePosition.Bottom))
					{
						points[0] = absoluteRectangle.Location;
						points[1] = new PointF(absoluteRectangle.Right, absoluteRectangle.Y);
						points[2] = new PointF(absoluteRectangle.Right, absoluteRectangle.Bottom);
						points[3] = new PointF(absoluteRectangle.X, absoluteRectangle.Bottom);
						points[4] = new PointF(absoluteRectangle.X, (absoluteRectangle.Y + (absoluteRectangle.Height / 2f)) + num);
						points[5] = absolutePoint;
						points[6] = new PointF(absoluteRectangle.X, (absoluteRectangle.Y + (absoluteRectangle.Height / 2f)) - num);
					}
					path = new GraphicsPath();
					path.AddLines(points);
					path.CloseAllFigures();
					graphics.DrawPathAbs(path, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, PenAlignment.Center, this.ShadowOffset, this.ShadowColor);
				}
			}
			if (!flag)
			{
				graphics.FillRectangleRel(rectanglePosition, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, this.ShadowColor, this.ShadowOffset, PenAlignment.Center);
				path = new GraphicsPath();
				path.AddRectangle(graphics.GetAbsoluteRectangle(rectanglePosition));
			}
			base.DrawText(graphics, rectanglePosition, false, false);
			return path;
		}

		private GraphicsPath DrawRectangleLineCallout(ChartGraphics graphics, RectangleF rectanglePosition, PointF anchorPoint, bool drawRectangle)
		{
			if (drawRectangle)
			{
				graphics.FillRectangleRel(rectanglePosition, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, this.ShadowColor, this.ShadowOffset, PenAlignment.Center);
				base.DrawText(graphics, rectanglePosition, false, false);
			}
			else
			{
				rectanglePosition = base.DrawText(graphics, rectanglePosition, false, true);
				SizeF relativeSize = graphics.GetRelativeSize(new SizeF(2f, 2f));
				rectanglePosition.Inflate(relativeSize);
			}
			GraphicsPath path = new GraphicsPath();
			path.AddRectangle(graphics.GetAbsoluteRectangle(rectanglePosition));
			PointF point = new PointF(rectanglePosition.X, rectanglePosition.Bottom);
			PointF tf2 = new PointF(rectanglePosition.Right, rectanglePosition.Bottom);
			if (!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y))
			{
				if (!rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y))
				{
					PointF empty = PointF.Empty;
					if (anchorPoint.X < rectanglePosition.X)
					{
						empty.X = rectanglePosition.X;
					}
					else if (anchorPoint.X > rectanglePosition.Right)
					{
						empty.X = rectanglePosition.Right;
					}
					else
					{
						empty.X = rectanglePosition.X + (rectanglePosition.Width / 2f);
					}
					if (anchorPoint.Y < rectanglePosition.Y)
					{
						empty.Y = rectanglePosition.Y;
					}
					else if (anchorPoint.Y > rectanglePosition.Bottom)
					{
						empty.Y = rectanglePosition.Bottom;
					}
					else
					{
						empty.Y = rectanglePosition.Y + (rectanglePosition.Height / 2f);
					}
					bool flag = false;
					LineCap flat = LineCap.Flat;
					if (this.CalloutAnchorCap != LineAnchorCapStyle.None)
					{
						flag = true;
						flat = graphics.Pen.StartCap;
						if (this.CalloutAnchorCap == LineAnchorCapStyle.Arrow)
						{
							if (this.LineWidth < 4)
							{
								int num = 3 - this.LineWidth;
								graphics.Pen.StartCap = LineCap.Custom;
								graphics.Pen.CustomStartCap = new AdjustableArrowCap((float)(this.LineWidth + num), (float)(this.LineWidth + num), true);
							}
							else
							{
								graphics.Pen.StartCap = LineCap.ArrowAnchor;
							}
						}
						else if (this.CalloutAnchorCap == LineAnchorCapStyle.Diamond)
						{
							graphics.Pen.StartCap = LineCap.DiamondAnchor;
						}
						else if (this.CalloutAnchorCap == LineAnchorCapStyle.Round)
						{
							graphics.Pen.StartCap = LineCap.RoundAnchor;
						}
						else if (this.CalloutAnchorCap == LineAnchorCapStyle.Square)
						{
							graphics.Pen.StartCap = LineCap.SquareAnchor;
						}
					}
					graphics.DrawLineAbs(this.LineColor, this.LineWidth, this.LineDashStyle, graphics.GetAbsolutePoint(anchorPoint), graphics.GetAbsolutePoint(empty), this.ShadowColor, this.ShadowOffset);
					using (GraphicsPath path2 = new GraphicsPath())
					{
						path2.AddLine(graphics.GetAbsolutePoint(anchorPoint), graphics.GetAbsolutePoint(empty));
						path2.Widen(new Pen(Color.Black, (float)(this.LineWidth + 2)));
						path.SetMarkers();
						path.AddPath(path2, false);
					}
					if (flag)
					{
						graphics.Pen.StartCap = flat;
					}
					if (anchorPoint.Y < rectanglePosition.Y)
					{
						point.Y = rectanglePosition.Y;
						tf2.Y = rectanglePosition.Y;
					}
					else if ((anchorPoint.Y > rectanglePosition.Y) && (anchorPoint.Y < rectanglePosition.Bottom))
					{
						point.Y = rectanglePosition.Y;
						tf2.Y = rectanglePosition.Bottom;
						if (anchorPoint.X < rectanglePosition.X)
						{
							point.X = rectanglePosition.X;
							tf2.X = rectanglePosition.X;
						}
						else
						{
							point.X = rectanglePosition.Right;
							tf2.X = rectanglePosition.Right;
						}
					}
				}
				if (!drawRectangle)
				{
					graphics.DrawLineAbs(this.LineColor, this.LineWidth, this.LineDashStyle, graphics.GetAbsolutePoint(point), graphics.GetAbsolutePoint(tf2), this.ShadowColor, this.ShadowOffset);
					using (GraphicsPath path3 = new GraphicsPath())
					{
						path3.AddLine(graphics.GetAbsolutePoint(point), graphics.GetAbsolutePoint(tf2));
						path3.Widen(new Pen(Color.Black, (float)(this.LineWidth + 2)));
						path.SetMarkers();
						path.AddPath(path3, false);
					}
				}
			}
			return path;
		}

		private GraphicsPath DrawRoundedRectCallout(ChartGraphics graphics, RectangleF rectanglePosition, PointF anchorPoint, bool isEllipse)
		{
			RectangleF absoluteRectangle = graphics.GetAbsoluteRectangle(rectanglePosition);
			if ((absoluteRectangle.Width <= 0f) || (absoluteRectangle.Height <= 0f))
			{
				return null;
			}
			GraphicsPath path = new GraphicsPath();
			if (isEllipse)
			{
				path.AddEllipse(absoluteRectangle);
			}
			else
			{
				float cornerRadius = Math.Min(absoluteRectangle.Width, absoluteRectangle.Height) / 5f;
				path = this.CreateRoundedRectPath(absoluteRectangle, cornerRadius);
			}
			if ((!float.IsNaN(anchorPoint.X) && !float.IsNaN(anchorPoint.Y)) && !rectanglePosition.Contains(anchorPoint.X, anchorPoint.Y))
			{
				PointF absolutePoint = graphics.GetAbsolutePoint(new PointF(anchorPoint.X, anchorPoint.Y));
				path.Flatten();
				PointF[] pathPoints = path.PathPoints;
				int index = 0;
				int num3 = 0;
				float maxValue = float.MaxValue;
				foreach (PointF tf2 in pathPoints)
				{
					float num5 = tf2.X - absolutePoint.X;
					float num6 = tf2.Y - absolutePoint.Y;
					float num7 = (num5 * num5) + (num6 * num6);
					if (num7 < maxValue)
					{
						maxValue = num7;
						index = num3;
					}
					num3++;
				}
				pathPoints[index] = absolutePoint;
				path.Reset();
				path.AddLines(pathPoints);
				path.CloseAllFigures();
			}
			graphics.DrawPathAbs(path, this.BackColor, this.BackHatchStyle, string.Empty, ChartImageWrapMode.Scaled, Color.Empty, ChartImageAlignmentStyle.Center, this.BackGradientStyle, this.BackSecondaryColor, this.LineColor, this.LineWidth, this.LineDashStyle, PenAlignment.Center, this.ShadowOffset, this.ShadowColor);
			base.DrawText(graphics, rectanglePosition, true, false);
			return path;
		}

		private static GraphicsPath GetCloudOutlinePath(RectangleF position)
		{
			if (_cloudOutlinePath == null)
			{
				GetCloudPath(position);
			}
			GraphicsPath path = (GraphicsPath)_cloudOutlinePath.Clone();
			Matrix matrix = new Matrix();
			matrix.Translate(-_cloudBounds.X, -_cloudBounds.Y);
			path.Transform(matrix);
			matrix = new Matrix();
			matrix.Translate(position.X, position.Y);
			matrix.Scale(position.Width / _cloudBounds.Width, position.Height / _cloudBounds.Height);
			path.Transform(matrix);
			return path;
		}

		private static GraphicsPath GetCloudPath(RectangleF position)
		{
			if (_cloudPath == null)
			{
				_cloudPath = new GraphicsPath();
				_cloudPath.AddBezier((float)1689.5f, (float)1998.6f, (float)1581.8f, (float)2009.4f, (float)1500f, (float)2098.1f, (float)1500f, (float)2204f);
				_cloudPath.AddBezier((float)1500f, (float)2204f, (float)1499.9f, (float)2277.2f, (float)1539.8f, (float)2345.1f, (float)1604.4f, (float)2382.1f);
				_cloudPath.AddBezier((float)1603.3f, (float)2379.7f, (float)1566.6f, (float)2417.8f, (float)1546.2f, (float)2468.1f, (float)1546.2f, (float)2520.1f);
				_cloudPath.AddBezier((float)1546.2f, (float)2520.1f, (float)1546.2f, (float)2633.7f, (float)1641.1f, (float)2725.7f, (float)1758.1f, (float)2725.7f);
				_cloudPath.AddBezier((float)1758.1f, (float)2725.7f, (float)1766.3f, (float)2725.6f, (float)1774.6f, (float)2725.2f, (float)1782.8f, (float)2724.2f);
				_cloudPath.AddBezier((float)1781.7f, (float)2725.6f, (float)1848.5f, (float)2839.4f, (float)1972.8f, (float)2909.7f, (float)2107.3f, (float)2909.7f);
				_cloudPath.AddBezier((float)2107.3f, (float)2909.7f, (float)2175.4f, (float)2909.7f, (float)2242.3f, (float)2891.6f, (float)2300.6f, (float)2857.4f);
				_cloudPath.AddBezier((float)2300f, (float)2857.6f, (float)2360.9f, (float)2946.5f, (float)2463.3f, (float)2999.7f, (float)2572.9f, (float)2999.7f);
				_cloudPath.AddBezier((float)2572.9f, (float)2999.7f, (float)2717.5f, (float)2999.7f, (float)2845.2f, (float)2907.4f, (float)2887.1f, (float)2772.5f);
				_cloudPath.AddBezier((float)2887.4f, (float)2774.3f, (float)2932.1f, (float)2801.4f, (float)2983.6f, (float)2815.7f, (float)3036.3f, (float)2815.7f);
				_cloudPath.AddBezier((float)3036.3f, (float)2815.7f, (float)3190.7f, (float)2815.7f, (float)3316.3f, (float)2694.8f, (float)3317.5f, (float)2544.8f);
				_cloudPath.AddBezier((float)3317f, (float)2544.1f, (float)3479.2f, (float)2521.5f, (float)3599.7f, (float)2386.5f, (float)3599.7f, (float)2227.2f);
				_cloudPath.AddBezier((float)3599.7f, (float)2227.2f, (float)3599.7f, (float)2156.7f, (float)3575.7f, (float)2088.1f, (float)3531.6f, (float)2032.2f);
				_cloudPath.AddBezier((float)3530.9f, (float)2032f, (float)3544.7f, (float)2000.6f, (float)3551.9f, (float)1966.7f, (float)3551.9f, (float)1932.5f);
				_cloudPath.AddBezier((float)3551.9f, (float)1932.5f, (float)3551.9f, (float)1818.6f, (float)3473.5f, (float)1718.8f, (float)3360.7f, (float)1688.8f);
				_cloudPath.AddBezier((float)3361.6f, (float)1688.3f, (float)3341.4f, (float)1579.3f, (float)3243.5f, (float)1500f, (float)3129.3f, (float)1500f);
				_cloudPath.AddBezier((float)3129.3f, (float)1500f, (float)3059.8f, (float)1499.9f, (float)2994f, (float)1529.6f, (float)2949.1f, (float)1580.9f);
				_cloudPath.AddBezier((float)2949.5f, (float)1581.3f, (float)2909.4f, (float)1530f, (float)2847f, (float)1500f, (float)2780.8f, (float)1500f);
				_cloudPath.AddBezier((float)2780.8f, (float)1500f, (float)2700.4f, (float)1499.9f, (float)2626.8f, (float)1544.2f, (float)2590.9f, (float)1614.2f);
				_cloudPath.AddBezier((float)2591.7f, (float)1617.6f, (float)2543.2f, (float)1571.1f, (float)2477.9f, (float)1545.1f, (float)2409.8f, (float)1545.1f);
				_cloudPath.AddBezier((float)2409.8f, (float)1545.1f, (float)2313.9f, (float)1545.1f, (float)2225.9f, (float)1596.6f, (float)2180.8f, (float)1679f);
				_cloudPath.AddBezier((float)2180.1f, (float)1680.7f, (float)2129.7f, (float)1652f, (float)2072.4f, (float)1636.9f, (float)2014.1f, (float)1636.9f);
				_cloudPath.AddBezier((float)2014.1f, (float)1636.9f, (float)1832.8f, (float)1636.9f, (float)1685.9f, (float)1779.8f, (float)1685.9f, (float)1956f);
				_cloudPath.AddBezier((float)1685.9f, (float)1956f, (float)1685.8f, (float)1970.4f, (float)1686.9f, (float)1984.8f, (float)1688.8f, (float)1999f);
				_cloudPath.CloseAllFigures();
				_cloudOutlinePath = new GraphicsPath();
				_cloudOutlinePath.AddBezier((float)1604.4f, (float)2382.1f, (float)1636.8f, (float)2400.6f, (float)1673.6f, (float)2410.3f, (float)1711.2f, (float)2410.3f);
				_cloudOutlinePath.AddBezier((float)1711.2f, (float)2410.3f, (float)1716.6f, (float)2410.3f, (float)1722.2f, (float)2410.2f, (float)1727.6f, (float)2409.8f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)1782.8f, (float)2724.2f, (float)1801.3f, (float)2722.2f, (float)1819.4f, (float)2717.7f, (float)1836.7f, (float)2711f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)2267.6f, (float)2797.2f, (float)2276.1f, (float)2818.4f, (float)2287f, (float)2838.7f, (float)2300f, (float)2857.6f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)2887.1f, (float)2772.5f, (float)2893.8f, (float)2750.9f, (float)2898.1f, (float)2728.7f, (float)2900f, (float)2706.3f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)3460.5f, (float)2124.9f, (float)3491f, (float)2099.7f, (float)3515f, (float)2067.8f, (float)3530.9f, (float)2032f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)3365.3f, (float)1732.2f, (float)3365.3f, (float)1731.1f, (float)3365.4f, (float)1730.1f, (float)3365.4f, (float)1729f);
				_cloudOutlinePath.AddBezier((float)3365.4f, (float)1729f, (float)3365.4f, (float)1715.3f, (float)3364.1f, (float)1701.7f, (float)3361.6f, (float)1688.3f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)2949.1f, (float)1580.9f, (float)2934.4f, (float)1597.8f, (float)2922.3f, (float)1616.6f, (float)2913.1f, (float)1636.9f);
				_cloudOutlinePath.CloseFigure();
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)2590.9f, (float)1614.2f, (float)2583.1f, (float)1629.6f, (float)2577.2f, (float)1645.8f, (float)2573.4f, (float)1662.5f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)2243.3f, (float)1727.5f, (float)2224.2f, (float)1709.4f, (float)2203f, (float)1693.8f, (float)2180.1f, (float)1680.7f);
				_cloudOutlinePath.StartFigure();
				_cloudOutlinePath.AddBezier((float)1688.8f, (float)1999f, (float)1691.1f, (float)2015.7f, (float)1694.8f, (float)2032.2f, (float)1699.9f, (float)2048.3f);
				_cloudOutlinePath.CloseAllFigures();
				_cloudBounds = _cloudPath.GetBounds();
			}
			GraphicsPath path = (GraphicsPath)_cloudPath.Clone();
			Matrix matrix = new Matrix();
			matrix.Translate(-_cloudBounds.X, -_cloudBounds.Y);
			path.Transform(matrix);
			matrix = new Matrix();
			matrix.Translate(position.X, position.Y);
			matrix.Scale(position.Width / _cloudBounds.Width, position.Height / _cloudBounds.Height);
			path.Transform(matrix);
			return path;
		}

		internal static PointF GetIntersectionX(PointF firstPoint, PointF secondPoint, float pointX)
		{
			PointF tf = new PointF();
			tf.X = pointX;
			tf.Y = (((pointX - firstPoint.X) * (secondPoint.Y - firstPoint.Y)) / (secondPoint.X - firstPoint.X)) + firstPoint.Y;
			return tf;
		}

		internal static PointF GetIntersectionY(PointF firstPoint, PointF secondPoint, float pointY)
		{
			PointF tf = new PointF();
			tf.Y = pointY;
			tf.X = (((pointY - firstPoint.Y) * (secondPoint.X - firstPoint.X)) / (secondPoint.Y - firstPoint.Y)) + firstPoint.X;
			return tf;
		}

		internal override RectangleF GetTextSpacing(out bool annotationRelative)
		{
			RectangleF textSpacing = base.GetTextSpacing(out annotationRelative);
			if ((this._calloutStyle == CalloutStyle.Cloud) || (this._calloutStyle == CalloutStyle.Ellipse))
			{
				textSpacing = new RectangleF(4f, 4f, 4f, 4f);
				annotationRelative = true;
				return textSpacing;
			}
			if (this._calloutStyle == CalloutStyle.RoundedRectangle)
			{
				textSpacing = new RectangleF(1f, 1f, 1f, 1f);
				annotationRelative = true;
			}
			return textSpacing;
		}

		internal override bool IsAnchorDrawn()
		{
			return true;
		}

		internal override void Paint(Chart chart, ChartGraphics graphics)
		{
			PointF empty = PointF.Empty;
			PointF anchorLocation = PointF.Empty;
			SizeF size = SizeF.Empty;
			this.GetRelativePosition(out empty, out size, out anchorLocation);
			PointF tf3 = new PointF(empty.X + size.Width, empty.Y + size.Height);
			RectangleF rect = new RectangleF(empty, new SizeF(tf3.X - empty.X, tf3.Y - empty.Y));
			RectangleF rectanglePosition = new RectangleF(rect.Location, rect.Size);
			if (rectanglePosition.Width < 0f)
			{
				rectanglePosition.X = rectanglePosition.Right;
				rectanglePosition.Width = -rectanglePosition.Width;
			}
			if (rectanglePosition.Height < 0f)
			{
				rectanglePosition.Y = rectanglePosition.Bottom;
				rectanglePosition.Height = -rectanglePosition.Height;
			}
			if ((float.IsNaN(rectanglePosition.X) || float.IsNaN(rectanglePosition.Y)) || (float.IsNaN(rectanglePosition.Right) || float.IsNaN(rectanglePosition.Bottom)))
			{
				return;
			}
			GraphicsPath path = null;
			if (base.Common.ProcessModePaint)
			{
				switch (this._calloutStyle)
				{
					case CalloutStyle.SimpleLine:
						path = this.DrawRectangleLineCallout(graphics, rectanglePosition, anchorLocation, false);
						break;

					case CalloutStyle.Borderline:
						path = this.DrawRectangleLineCallout(graphics, rectanglePosition, anchorLocation, true);
						break;

					case CalloutStyle.Cloud:
						path = this.DrawCloudCallout(graphics, rectanglePosition, anchorLocation);
						break;

					case CalloutStyle.Rectangle:
						path = this.DrawRectangleCallout(graphics, rectanglePosition, anchorLocation);
						break;

					case CalloutStyle.RoundedRectangle:
						path = this.DrawRoundedRectCallout(graphics, rectanglePosition, anchorLocation, false);
						break;

					case CalloutStyle.Ellipse:
						path = this.DrawRoundedRectCallout(graphics, rectanglePosition, anchorLocation, true);
						break;

					case CalloutStyle.Perspective:
						path = this.DrawPerspectiveCallout(graphics, rectanglePosition, anchorLocation);
						break;
				}
			}
			if (base.Common.ProcessModeRegions)
			{
				if (path != null)
				{
					GraphicsPathIterator iterator = new GraphicsPathIterator(path);
					using (GraphicsPath path2 = new GraphicsPath())
					{
						while (iterator.NextMarker(path2) > 0)
						{
							base.Common.HotRegionsList.AddHotRegion(graphics, path2, false, base.ReplaceKeywords(this.ToolTip), base.ReplaceKeywords(this.Url), base.ReplaceKeywords(this.MapAreaAttributes), base.ReplaceKeywords(base.PostBackValue), this, ChartElementType.Annotation);
							path2.Reset();
						}
						goto Label_028E;
					}
				}
				base.Common.HotRegionsList.AddHotRegion(rectanglePosition, base.ReplaceKeywords(this.ToolTip), base.ReplaceKeywords(this.Url), base.ReplaceKeywords(this.MapAreaAttributes), base.ReplaceKeywords(base.PostBackValue), this, ChartElementType.Annotation, string.Empty);
			}
		Label_028E:
			if (path != null)
			{
				path.Dispose();
			}
			this.PaintSelectionHandles(graphics, rect, null);
		}

		private void PathAddLineAsSegments(GraphicsPath path, float x1, float y1, float x2, float y2, int segments)
		{
			if (x1 == x2)
			{
				float num = (y2 - y1) / ((float)segments);
				for (int i = 0; i < segments; i++)
				{
					path.AddLine(x1, y1, x1, y1 + num);
					y1 += num;
				}
			}
			else
			{
				if (y1 != y2)
				{
					throw new InvalidOperationException(SR.ExceptionAnnotationPathAddLineAsSegmentsInvalid);
				}
				float num3 = (x2 - x1) / ((float)segments);
				for (int j = 0; j < segments; j++)
				{
					path.AddLine(x1, y1, x1 + num3, y1);
					x1 += num3;
				}
			}
		}

		[SRDescription("DescriptionAttributeAnchorAlignment"), SRCategory("CategoryAttributeAnchor"), DefaultValue(typeof(ContentAlignment), "BottomLeft")]
		public override ContentAlignment AnchorAlignment
		{
			get
			{
				return base.AnchorAlignment;
			}
			set
			{
				base.AnchorAlignment = value;
			}
		}

		[SRCategory("CategoryAttributeAnchor"), RefreshProperties(RefreshProperties.All), SRDescription("DescriptionAttributeCalloutAnnotation_AnchorOffsetX"), DefaultValue((double)3.0)]
		public override double AnchorOffsetX
		{
			get
			{
				return base.AnchorOffsetX;
			}
			set
			{
				base.AnchorOffsetX = value;
			}
		}

		[RefreshProperties(RefreshProperties.All), DefaultValue((double)3.0), SRCategory("CategoryAttributeAnchor"), SRDescription("DescriptionAttributeCalloutAnnotation_AnchorOffsetY")]
		public override double AnchorOffsetY
		{
			get
			{
				return base.AnchorOffsetY;
			}
			set
			{
				base.AnchorOffsetY = value;
			}
		}

		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SerializationVisibility(SerializationVisibility.Hidden), SRDescription("DescriptionAttributeAnnotationType"), Bindable(true), Browsable(false), EditorBrowsable(EditorBrowsableState.Never), SRCategory("CategoryAttributeMisc")]
		public override string AnnotationType
		{
			get
			{
				return "Callout";
			}
		}

		[DefaultValue(typeof(Color), ""), SRCategory("CategoryAttributeAppearance"), SRDescription("DescriptionAttributeBackColor"), NotifyParentProperty(true), TypeConverter(typeof(ColorConverter)), Editor(typeof(ChartColorEditor), typeof(UITypeEditor)), Browsable(true)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
			}
		}

		[Editor(typeof(GradientEditor), typeof(UITypeEditor)), SRCategory("CategoryAttributeAppearance"), Browsable(true), DefaultValue(0), NotifyParentProperty(true), SRDescription("DescriptionAttributeBackGradientStyle")]
		public override GradientStyle BackGradientStyle
		{
			get
			{
				return base.BackGradientStyle;
			}
			set
			{
				base.BackGradientStyle = value;
			}
		}

		[DefaultValue(0), Editor(typeof(HatchStyleEditor), typeof(UITypeEditor)), SRCategory("CategoryAttributeAppearance"), Browsable(true), NotifyParentProperty(true), SRDescription("DescriptionAttributeBackHatchStyle")]
		public override ChartHatchStyle BackHatchStyle
		{
			get
			{
				return base.BackHatchStyle;
			}
			set
			{
				base.BackHatchStyle = value;
			}
		}

		[Browsable(true), Editor(typeof(ChartColorEditor), typeof(UITypeEditor)), SRCategory("CategoryAttributeAppearance"), DefaultValue(typeof(Color), ""), NotifyParentProperty(true), SRDescription("DescriptionAttributeBackSecondaryColor"), TypeConverter(typeof(ColorConverter))]
		public override Color BackSecondaryColor
		{
			get
			{
				return base.BackSecondaryColor;
			}
			set
			{
				base.BackSecondaryColor = value;
			}
		}

		[SRDescription("DescriptionAttributeCalloutAnnotation_CalloutAnchorCap"), SRCategory("CategoryAttributeAppearance"), Bindable(true), DefaultValue(1)]
		public virtual LineAnchorCapStyle CalloutAnchorCap
		{
			get
			{
				return this._calloutAnchorCap;
			}
			set
			{
				this._calloutAnchorCap = value;
				this.Invalidate();
			}
		}

		[SRCategory("CategoryAttributeAppearance"), SRDescription("DescriptionAttributeCalloutAnnotation_CalloutStyle"), Bindable(true), DefaultValue(3), ParenthesizePropertyName(true)]
		public virtual CalloutStyle CalloutStyle
		{
			get
			{
				return this._calloutStyle;
			}
			set
			{
				this._calloutStyle = value;
				base.ResetCurrentRelativePosition();
				base.contentSize = SizeF.Empty;
				this.Invalidate();
			}
		}

		[DefaultValue(typeof(Color), "Black"), SRCategory("CategoryAttributeAppearance"), SRDescription("DescriptionAttributeLineColor"), Browsable(true), Editor(typeof(ChartColorEditor), typeof(UITypeEditor)), TypeConverter(typeof(ColorConverter))]
		public override Color LineColor
		{
			get
			{
				return base.LineColor;
			}
			set
			{
				base.LineColor = value;
			}
		}

		[Browsable(true), SRCategory("CategoryAttributeAppearance"), SRDescription("DescriptionAttributeLineDashStyle"), DefaultValue(5)]
		public override ChartDashStyle LineDashStyle
		{
			get
			{
				return base.LineDashStyle;
			}
			set
			{
				base.LineDashStyle = value;
			}
		}

		[SRCategory("CategoryAttributeAppearance"), Browsable(true), SRDescription("DescriptionAttributeLineWidth"), DefaultValue(1)]
		public override int LineWidth
		{
			get
			{
				return base.LineWidth;
			}
			set
			{
				base.LineWidth = value;
			}
		}

		[DefaultValue(1), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SerializationVisibility(SerializationVisibility.Hidden), SRDescription("DescriptionAttributeSelectionPointsStyle"), SRCategory("CategoryAttributeAppearance"), ParenthesizePropertyName(true), Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
		internal override SelectionPointsStyle SelectionPointsStyle
		{
			get
			{
				return SelectionPointsStyle.Rectangle;
			}
		}
	}
}

